package com.igoal.service.dwr;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.validator.EmailValidator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import com.igoal.dto.CompanyDTO;
import com.igoal.dto.HobbyDTO;
import com.igoal.dto.SchoolDTO;
import com.igoal.dto.UserDTO;
import com.igoal.dto.UserInfoDTO;
import com.igoal.dto.UserStatusDTO;
import com.igoal.service.ActionLoggerService;
import com.igoal.service.ContactVendorEnum;
import com.igoal.service.SaveResult;
import com.igoal.service.UserAccountService;
import com.igoal.service.UserManagerExt;
import com.igoal.utils.StringUtils;

@Service("userManagerDWR")
public class UserManagerDWRImpl extends BaseDWRService implements UserManagerDWR{
	@Autowired
	UserManagerExt userManagerExt;
	
	@Autowired
	UserAccountService userAccountService;
	
	@Autowired
	ActionLoggerService actionLoggerService;

	public void setUserManagerExt(UserManagerExt userManagerExt) {
		this.userManagerExt = userManagerExt;
	}

	public void setActionLoggerService(ActionLoggerService actionLoggerService) {
		this.actionLoggerService = actionLoggerService;
	}

	public boolean isLogined() {
		return isLoginUser();
	}
	
	public UserDTO login(String username, String password) {
		try {
			UserDTO user = userManagerExt.login(username, password);
			if (user != null) {
//				setUserSession(user);
				return user;
			}
			//TODO: review CustomeAuthentication
		} catch (Exception e) {
			logger.error(e);
		}
		return null;
	}

	public void addFriend(Long friendId) {
		if(!isLogined()){
			debug("User session is expired when requested add new friend.");
		}
		
		String username = getUserInSession();
		Assert.notNull(username);
		Assert.isTrue(!username.equalsIgnoreCase("roleAnonymous"));
		UserDTO userSession = userManagerExt.getUserByUsername(username);
		if(userSession != null){
			userManagerExt.addFriend(userSession, friendId);
		}else{
			debug("User session is expired when requested add new friend.");
		}
	}
	
	public void addFriends(Long[] friendIds) {
		if(!isLogined()){
			debug("User session is expired when requested add new friend.");
		}
		
		String username = getUserInSession();
		Assert.notNull(username);
		Assert.isTrue(!username.equalsIgnoreCase("roleAnonymous"));
		UserDTO userSession = userManagerExt.getUserByUsername(username);
		
		if(userSession != null){
			userManagerExt.addFriends(userSession, friendIds);
		}else{
			debug("User session is expired when requested add new friends.");
		}
	}

	public UserStatusDTO getUserStatus() {
		if(!isLogined()){
			debug("User session is expired when requested get user status.");
		}
		
		String username = getUserInSession();
		Assert.notNull(username);
		Assert.isTrue(!username.equalsIgnoreCase("roleAnonymous"));
		UserDTO userSession = userManagerExt.getUserByUsername(username);
		
		if(userSession != null)
			return userManagerExt.getUserStatus(userSession);
		
		return null;
	}
	
	public int saveUserStatus(String status) {
		if(!isLogined()){
			debug("User session is expired when requested update status.");
		}
		
		String username = getUserInSession();
		Assert.notNull(username);
//		Assert.isTrue(!username.equalsIgnoreCase("roleAnonymous"));
		UserDTO userSession = userManagerExt.getUserByUsername(username);
		
		return userManagerExt.saveUserStatus(userSession, status);
	}
	
	public Long register(UserDTO newUser) {
		String username = newUser.getUsername();
		String password = newUser.getPassword();
		String email = newUser.getEmail();
		
		if(StringUtils.isBlank(username) || StringUtils.isContainingUnicodeOrSpecialChar(username) || StringUtils.hasSpaceInside(username))
			return new Long(SaveResult.FAIL);
		
		if(StringUtils.isBlank(password) || password.length() < 6)
			return new Long(SaveResult.FAIL);
		
		if(StringUtils.isBlank(email) || !EmailValidator.getInstance().isValid(email))
			return new Long(SaveResult.FAIL);
		
		Long newId = userAccountService.register(newUser);
		if(newId > 0){
			return newId;
		}			
		
		return new Long(SaveResult.FAIL);
	}
	
	public List<UserDTO> searchUser(String text) {		
		if(!isLogined()) return new ArrayList<UserDTO>();
		String userInSession = getUserInSession();
		UserDTO user = userManagerExt.getUserByUsername(userInSession);
		Assert.notNull(user, "Data failure!");
		
		List<UserDTO> result = userManagerExt.searchUser(text);
		if(result.size() > 0){
			result.remove(user);
		}
		return result;
	}

	public List<UserDTO> getUsersExceptForMe() {
		return searchUser("");
	}

	public long validateEmail(String email) {
		return userManagerExt.validateEmail(email);
	}

	public long validateUsername(String username) {		
		return userManagerExt.validateUsername(username);
	}
	
	public List<UserDTO> findContacts(ContactVendorEnum vendor,
			String username, String password) {
		return userManagerExt.findContacts(vendor, username, password);
	}

	public int updateStatus(String status) {
		if(!isLogined()){
			debug("User session is expired when requested update status.");
			return SaveResult.FAIL;
		}
		
		if(StringUtils.isEmpty(status))
			return SaveResult.FAIL;
		
		String username = getUserInSession();
		Assert.notNull(username);
		Assert.isTrue(!username.equalsIgnoreCase("roleAnonymous"));
		UserDTO userSession = userManagerExt.getUserByUsername(username);
		
		return userManagerExt.saveUserStatus(userSession, status);
	}

	public int likeThisComment(long commentId) {		
		if(!isLogined()){
			debug("User session is expired when requested like.");
			return SaveResult.FAIL;
		}
				
		//TODO: implement
		return SaveResult.FAIL;
	}

	public int likeThisDoneEntry(long entryId) {
		if(!isLogined()){
			debug("User session is expired when requested like.");
			return SaveResult.FAIL;
		}
		
		try{
			return userManagerExt.likeThisDoneEntry(getUserInSession(), entryId);
		}catch (Exception e) {
			logger.error(e);
			return SaveResult.FAIL;
		}
	}

	public int likeThisEntry(long entryId) {
		if(!isLogined()){
			debug("User session is expired when requested like");
			return SaveResult.FAIL;
		}
		
		try{
			return userManagerExt.likeThisEntry(getUserInSession(), entryId);
		}catch (Exception e) {
			logger.error(e);
			return SaveResult.FAIL;
		}
	}
	
	public int unlikeThisDoneEntry(long entryId) {
		if(!isLogined()){
			debug("User session is expired when requested unlike.");
			return SaveResult.FAIL;
		}
		
		try{
			return userManagerExt.unlikeThisDoneEntry(getUserInSession(), entryId);
		}catch (Exception e) {
			logger.error(e);
			return SaveResult.FAIL;
		}
	}

	public int unlikeThisEntry(long entryId) {
		if(!isLogined()){
			debug("User session is expired when requested unlike.");
			return SaveResult.FAIL;
		}
		
		try{
			return userManagerExt.unlikeThisEntry(getUserInSession(), entryId);
		}catch (Exception e) {
			logger.error(e);
			return SaveResult.FAIL;
		}
	}

	public int unlikeThisComment(long commentId) {
		if(!isLogined()){
			debug("User session is expired when requested unlike.");
			return SaveResult.FAIL;
		}
				
		//TODO: implement
		return SaveResult.FAIL;
	}

	public int saveAboutMe(String aboutMe) {
		if(!isLogined()){
			debug("User session is expired when requested update aboutme.");
			return SaveResult.FAIL;
		}
		
		if(StringUtils.isEmpty(aboutMe))
			return SaveResult.FAIL;
		
		try{
			return userManagerExt.saveAboutMe(getUserInSession(), aboutMe);
		}catch (Exception e) {
			logger.error(e);
			return SaveResult.FAIL;
		}
	}

	public boolean checkUserPassword(String password) {
		return userManagerExt.checkPassword(password);
	}

	public int acceptFriend(String from) {
		if(!isLogined()){
			debug("User session is expired when requested add new friend.");
			return SaveResult.FAIL;
		}
		
		if(StringUtils.isBlank(from))
			return SaveResult.FAIL;
		
		String to = getUserInSession();
		return userManagerExt.acceptFriend(from, to);
	}

	public int refuseFriend(String from) {
		if(!isLogined()){
			debug("User session is expired when requested refuse new friend.");
			return SaveResult.FAIL;
		}
		
		if(StringUtils.isBlank(from))
			return SaveResult.FAIL;
		
		String to = getUserInSession();
		return userManagerExt.refuseFriend(from, to);
	}

	public int addCategories(Long[] categoryIds) {
		if(!isLogined()){
			debug("User session is expired when requested add new categories.");
			return SaveResult.FAIL;
		}
		
		if(categoryIds == null || categoryIds.length == 0)
			return SaveResult.FAIL;
				
		String username = getUserInSession();
		return userManagerExt.addCategories(username, categoryIds);
	}

	public int removeCategories(Long[] categoryIds) {
		if(!isLogined()){
			debug("User session is expired when requested remove categories.");
			return SaveResult.FAIL;
		}
		
		if(categoryIds == null || categoryIds.length == 0)
			return SaveResult.FAIL;
				
		String username = getUserInSession();
		return userManagerExt.removeCategories(username, categoryIds);
	}
	
	public int thumbStatus(Long statusId, boolean up){
		if(!isLogined()){
			debug("User session is expired when requested thumb up/down status.");
			return SaveResult.FAIL;
		}
		
		if(statusId == null || statusId <= 0L)
			return SaveResult.FAIL;
		
		String username = getUserInSession();
		if(up)
			return userManagerExt.thumbUpUserStatus(username, statusId);
		else
			return userManagerExt.thumbDownUserStatus(username, statusId);
	}

	public int countThumbDown(Long statusId) {
		if(statusId == null || statusId <= 0L)
			return 0;
		
		return userManagerExt.countUserStatusThumbedDown(statusId);
	}

	public int countThumbUp(Long statusId) {
		if(statusId == null || statusId <= 0L)
			return 0;
		
		return userManagerExt.countUserStatusThumbedUp(statusId);
	}

	public int markReadNotification(Long[] notificationIds) {
		if(!isLogined()){
			debug("User session is expired when requested mark read status on notification.");
			return SaveResult.FAIL;
		}
		
		String username = getUserInSession();
		return userManagerExt.markReadNotification(username, notificationIds);
	}

	public int cheerThisDoneEntry(Long entryId) {
		if(!isLogined()){
			debug("User session is expired when requested like.");
			return SaveResult.FAIL;
		}
		
		try{
			return userManagerExt.cheerThisDoneEntry(getUserInSession(), entryId);
		}catch (Exception e) {
			logger.error(e);
			return SaveResult.FAIL;
		}
	}

	public int cheerThisEntry(Long entryId) {
		if(!isLogined()){
			debug("User session is expired when requested cheer");
			return SaveResult.FAIL;
		}
		
		try{
			return userManagerExt.cheerThisEntry(getUserInSession(), entryId);
		}catch (Exception e) {
			logger.error(e);
			return SaveResult.FAIL;
		}
	}

	public int getNewNotification() {
		if(!isLogined()){
			debug("User session is expired when requested like");
			return 0;
		}
		
		String username = getUserInSession();
		int newNotificationCount = actionLoggerService.countNewNotificationLog(username, null, false);
		return newNotificationCount;
	}
	

	// public long addThought(String wallOwner, String thought, String privacy)
	// {
	// if (!isLogined()) {
	// debug("User session is expired");
	// return 0;
	// }
	// String postOwner = getUserInSession();
	// return userManagerExt.saveThought(postOwner, wallOwner, thought,
	// privacy);
	// }

	public int updateUserBasicInformation(UserInfoDTO dto) {
		if(isLogined() && dto != null){
			String username = getUserInSession();			
			return userAccountService.updateUserBasicInformation(username, dto.getFirstName(), dto.getMiddleName(), 
					dto.getLastName(), dto.getBirthdayDate(), dto.getBirthdayMonth(), dto.getBirthdayYear(), 
					dto.getMale(), dto.getAboutMe(), dto.getEmail());
		}
		return SaveResult.FAIL;
	}

	public int updateUserCompany(CompanyDTO dto) {
		// TODO Auto-generated method stub
		return 0;
	}

	public int updateUserContactInformation(UserInfoDTO dto) {
		if(isLogined() && dto != null){
			String username = getUserInSession();
			return userAccountService.updateUserContactInformation(username, dto.getYahoo(), dto.getSkype(), 
					dto.getFacebook(), dto.getWebsite(), dto.getMobile());
		}
		return SaveResult.FAIL;
	}

	public int updateUserResidentInformation(UserInfoDTO dto) {
		if(isLogined() && dto != null){
			String username = getUserInSession();
			Long cityId = dto.getCityId();
			return userAccountService.updateUserResidentInformation(username, dto.getAddress(), dto.getDistrict(), cityId);
		}
		return SaveResult.FAIL;
	}

	public int updateUserSchool(SchoolDTO dto) {
		// TODO Auto-generated method stub
		return 0;
	}

	public int updateUserSchools(SchoolDTO[] schools) {
		if(isLogined() && schools != null){
			String username = getUserInSession();
			return userAccountService.updateUserSchools(username, schools);
		}
		return SaveResult.FAIL;
	}

	public int updateUserCompanies(CompanyDTO[] companies) {
		if(isLogined() && companies!=null){
			String username = getUserInSession();
			return userAccountService.updateUserCompanies(username, companies);
		}
		return SaveResult.FAIL;
	}
	
	public int updateUserPassword(String oldPass, String newPass) {
		UserDTO user = userManagerExt.getUserByUsername(getUserInSession());
		return userManagerExt.saveUserPasswordInfo(user, oldPass, newPass);
	}
	
	public int updateUserHobbies(HobbyDTO[] hobbies){
		if(isLogined() && hobbies!=null){
			String username = getUserInSession();
			return userAccountService.updateUserHobbies(username, hobbies);
		}
		return SaveResult.FAIL;
	}

}
